// v-reveal 指令：元素进入可视区时执行淡入/位移动画
// 使用方式：
//  v-reveal="{ delay: 100, duration: 600, distance: 20, direction: 'up', once: true }"
//  direction 可选：'up' | 'down' | 'left' | 'right' | 'none'（仅淡入）

const OBSERVER_MAP = new WeakMap();

function applyInitialStyles(el, options) {
  const distance = options.distance ?? 20;
  const duration = options.duration ?? 600; // ms
  const delay = options.delay ?? 0; // ms
  const easing = options.easing ?? 'cubic-bezier(0.22, 1, 0.36, 1)';
  const direction = options.direction ?? 'up';

  let translate = '';
  switch (direction) {
    case 'down':
      translate = `translateY(-${distance}px)`;
      break;
    case 'left':
      translate = `translateX(${distance}px)`;
      break;
    case 'right':
      translate = `translateX(-${distance}px)`;
      break;
    case 'none':
      translate = 'none';
      break;
    case 'up':
    default:
      translate = `translateY(${distance}px)`;
  }

  el.style.opacity = '0';
  el.style.transform = translate;
  el.style.willChange = 'opacity, transform';
  el.style.transition = `opacity ${duration}ms ${easing} ${delay}ms, transform ${duration}ms ${easing} ${delay}ms`;
}

function reveal(el) {
  el.style.opacity = '1';
  el.style.transform = 'none';
}

function createObserver(el, options) {
  const once = options.once !== false; // 默认只触发一次
  const threshold = options.threshold ?? 0.15;
  const rootMargin = options.rootMargin ?? '0px 0px -5% 0px';

  const io = new IntersectionObserver((entries) => {
    entries.forEach((entry) => {
      if (entry.isIntersecting) {
        reveal(el);
        if (once) {
          io.unobserve(el);
        }
      } else if (!once) {
        // 离开视口时复原，允许重复播放
        applyInitialStyles(el, options);
      }
    });
  }, { threshold, rootMargin });

  io.observe(el);
  OBSERVER_MAP.set(el, io);
}

export default {
  // el: HTMLElement, binding: { value?: Options }
  beforeMount(el, binding) {
    const value = binding?.value || {};
    const options = {
      distance: value.distance,
      duration: value.duration,
      delay: value.delay,
      easing: value.easing,
      direction: value.direction,
      once: value.once,
      threshold: value.threshold,
      rootMargin: value.rootMargin,
    };
    applyInitialStyles(el, options);
    // 提前存起来，mounted 复用
    el.__vRevealOptions = options;
  },
  mounted(el) {
    const options = el.__vRevealOptions || {};
    createObserver(el, options);
  },
  updated(el, binding) {
    // 支持动态更新 delay 等参数
    const value = binding?.value || {};
    const options = { ...el.__vRevealOptions, ...value };
    el.__vRevealOptions = options;
  },
  unmounted(el) {
    const io = OBSERVER_MAP.get(el);
    if (io) {
      io.unobserve(el);
      io.disconnect();
      OBSERVER_MAP.delete(el);
    }
    delete el.__vRevealOptions;
  },
};


